let toast, debug, autoLoad, showTips, apiKey;
let normalStyle = 'color:#09F;font-weight:bold;';
let errorStyle = 'color:#F00;font-weight:bold;';
let log = console.log;

axlib.use(['toast'], main);

function main(plugins) {
  toast = plugins.toast;
  let repData = THIS.getData();
  let exData = THIS.getExtraData({format:'row'});
  THIS.clearExtraData();

  let $stateIcon = $('div[class*="axslot-icon"]');
  let stateIconId = $stateIcon.attr('id');
  let stateIcon = $axure(`#${stateIconId}`);
  // 是否可用，请求数据时为false，空闲时为true
  stateIcon.selected(true);

  binId = String(exData['仓库ID']);
  privy = Number(exData['私有仓库']) > 0;
  showTips = Number(exData['启用提示']) > 0;
  debug = Number(exData['启用调试']) > 0;
  apiKey = String(exData['API密钥']);
  autoLoad = String(exData['自动下载']);

  if (binId == '') {
    autoLoad = false;
  }

  if (debug) {
    console.group('%c[AXSLOT]', normalStyle);
    console.log('%c组件配置', normalStyle, exData);
    console.log('%c元件绑定', normalStyle, repData);
    console.groupEnd();
  }

  let bin = axlib.jsonbin({
    binId: binId,
    apiKey: apiKey,
    isPrivate: privy
  });

  if (!showTips) { log = toast = function(){}; }
  if (autoLoad !== undefined && autoLoad !== false) {
    let seconds = Number(autoLoad.replace(/s/gi, ''));

    if (seconds != NaN) {
      if (seconds === 1) {
        download({bin, icon:stateIcon});
      }
      else if (seconds > 1 && seconds < 10) {
        seconds = 10;
      }

      if (seconds >= 10) {
        log(`%c[AXSLOT] 已设置为每${seconds}秒下载一次.`, normalStyle);
        toast({text:`已设置为每${seconds}秒下载一次.`});

        download({bin, icon:stateIcon});
        setInterval(function(){
          download({bin, icon:stateIcon});
        }, seconds * 1000);
      }
    }
  }

  THIS.$repeater.on('REPEATER_DATA_UPDATED', (e, res) => {
    let isDataAction = res[4].value.indexOf('数据操作') != -1;
    let action = res[1].enabled.text;
    if (isDataAction == -1) return;

    // 下载数据
    if (action === '下载') {
      download({bin, icon:stateIcon});
    }

    // 上传数据
    if (action === '上传') {
      upload({bin, icon:stateIcon, data:repData});
    }

    // 新建仓库
    if (action === '新建') {
      toast({text:'正在创建仓库,请耐心等待~', hideAfter:false});
      bin.create(res => {
        log(`%c[AXSLOT] 创建仓库`, normalStyle, res);
        if (!res.metadata) {
          toast({text:`已有仓库ID：${res}，如想创建新仓库，请先清空当前ID，并填写API密钥!`, hideAfter:false, stack:1});
        } else {
          toast({text:`仓库已创建：${res.metadata.id}`, hideAfter:false, stack:1});
        }
      });
    }

    // 删除仓库
    if (action === '删除') {
      if (binId == '' || apiKey == '') {
        toast({text:'无法删除仓库,请确认已填写仓库ID和API密钥!', icon: 'error', hideAfter:false});
        return;
      }
      toast({text:'正在删除仓库,请耐心等待~', hideAfter:false});
      bin.del(res => {
        log('删除仓库 %o', res);
        toast({text:'仓库已成功删除!', hideAfter:false, stack:1});
      });
    }
  });
}

function upload({bin, icon, data}) {
  let localData = localStorage.getItem('axslot_data') || '{}';
  let oldData = JSON.parse(localData);
  let symData = getSymbolData(data);
  
  $.each(symData, (i, n) => {
    if (n.value !== undefined) return;
    $.each(oldData, (j, m) => {
      if (n.name === m.name) {
        symData[i] = {...m};
      }
    });
  });

  log(`%c[AXSLOT] 上传数据`, normalStyle, symData);
  localStorage.setItem('axslot_data', JSON.stringify(symData));

  icon.selected(false);
  toast({text:'上传数据中,请耐心等待~', hideAfter:false});

  bin.update(symData, res=>{
    icon.selected(true);
    toast({text:'数据上传完毕!', stack:1});
  });
}

function download({bin, icon}) {
  toast({ text:'下载数据中,请耐心等待~', hideAfter:false });
  icon.selected(false);
  bin.read(res => {
    log(`%c[AXSLOT] 下载数据`, normalStyle, res.record.data);
    if ( res.record.data === undefined ) { console.log(`%c[AXSLOT] 数据不匹配，请先上传~`, errorStyle); return; }

    // 把取消绑定的元件名记录下来，在下载数据赋值时自动跳过
    let latestData = THIS.getLatestData();
    let ignore = [];
    latestData.forEach(n=>{
      if (Number(n.enabled)==0) { ignore.push(n.symbol); }
    });

    applySymbolData(res.record.data, ignore);
    icon.selected(true);

    toast({text:'数据完成下载!', stack:1});
  });
}

function applySymbolData(allData, ignore) {
  for (let i=0; i<allData.length; i++) {
    let item = allData[i];

    let symbolName = item.name;
    let symbolType = item.type;
    let value = item.value;
    let symbol = $axure(`@${symbolName}`);
    let $symbol = symbol.$().eq(0);

    if (!item.enabled || ignore.includes(symbolName)) continue;

    if (symbolType == 'shape') {
      $symbol.children('.text').html(value);
    }
    else if (symbolType == 'dynamicPanel') {
      symbol.setPanelStateByIndex(value);
    }
    else if (symbolType == 'textBox') {
      $symbol.children('input').val(value);
    }
    else if (symbolType == 'textArea') {
     $symbol.children('textarea').val(value);
    }
    else if (symbolType == 'image') {
      $symbol.children('img').attr('src', value);
    }
    else if (symbolType == 'iframe') {
      $symbol.children('iframe').attr('src', value);
    }
  }
}

function getSymbolData(list) {
  let allData = [];
  for (let i=0; i<list.length; i++) {
    let item = list[i];
    let symbolName = item.sym;

    let enabled = item.enabled;
    if (enabled === undefined) { enabled = 1; }
    
    let symbolType = getSymbolType(symbolName);
    let symbol = $axure(`@${symbolName}`);
    let $symbol = symbol.$().eq(0);

    let value;
    if (symbolType == 'shape') {
      value = $symbol.children('.text').html().trim();
    }
    else if (symbolType == 'dynamicPanel') {
      let stateDiv = symbol.getCurrentPanelState();
      let stateId = $(stateDiv).id();
      value = Number(stateId.split('_state')[1]) + 1;
    }
    else if (symbolType == 'textBox') {
      value = $symbol.children('input').val();
    }
    else if (symbolType == 'textArea') {
      value = $symbol.children('textarea').val();
    }
    else if (symbolType == 'textArea') {
      value = $symbol.children('textarea').val();
    }
    else if (symbolType == 'image') {
      value = $symbol.children('img').attr('src');
    }
    else if (symbolType == 'dropList') {
      let select = $symbol.children('select');
      let items = select.children('option');
      let preset, current = symbol.text(), options = [];
      $.each(items, (i,n) => {
        let text = $(n).attr('value');
        if ($(n).attr('selected')) { preset = i; }
        if (text == current) { current = i; }
        options.push(text);
      });
      value = { preset, current, options };
    }
    else if (symbolType == 'listBox') {
      let select = $symbol.children('select');
      let items = select.children('option');
      let preset, current = symbol.text(), options = [];
      $.each(items, (i,n) => {
        let text = $(n).attr('value');
        if ($(n).attr('selected')) { preset = i; }
        if (text == current) { current = i; }
        options.push(text);
      });
      value = { preset, current, options };
    }
    else if (symbolType == 'iframe') {
      value = $symbol.children('iframe').attr('src');
    }
    else if (symbolType == 'radio') {
      value = {
        preset: symbol.selected(),
        current: $symbol.children('input[type="radio"]').attr('checked') == 'checked'
      };
    }
    else if (symbolType == 'checkbox') {
      value = {
        preset: symbol.selected(),
        current: $symbol.children('input[type="checkbox"]').attr('checked') == 'checked'
      };
    }
    else {
      value = undefined;
    }
    allData.push({
      name: symbolName,
      type: symbolType,
      enabled,
      value
    });
  }
  return allData;
}

function getSymbolType(name) {
  let $el = $axure(`@${name}`).$();
  let type;
  if ($el.children('.panel_state').length>0) {
    type = 'dynamicPanel';
  }
  else if ($el.children('input').length>0 && $el.children('input').attr('type')== 'text') {
    type = 'textBox';
  }
  else if ($el.children('textarea').length>0) {
    type = 'textArea';
  }
  else if ($el.children('input').length>0 && $el.children('input').attr('type')== 'checkbox') {
    type = 'checkbox';
  }
  else if ($el.children('input').length>0 && $el.children('input').attr('type')== 'radio') {
    type = 'radio';
  }
  else if ($el.children('select').length>0 && $el.children('select').css('appearance')=='menulist-button') {
    type = 'dropList';
  }
  else if ($el.children('select').length>0) {
    type = 'listBox';
  }
  else if ($el.children('iframe').length>0) {
    type = 'iframe';
  }
  else if ($el.children('.img').length>0) {
    type = 'image';
  }
  else if ($el.children('.text').length>0) {
    type = 'shape';
  }
  else if ($el.children().length==0) {
    type = 'hotSpot';
  }
  else if ($el.length==0) {
    type = undefined;
  }
  return type;
}